package org.example.word;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.Section;
import com.spire.doc.collections.ParagraphCollection;
import com.spire.doc.collections.SectionCollection;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.formatting.CharacterFormat;
import com.spire.pdf.PdfDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.example.util.FileUtils;
import java.io.*;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Pattern;

/**
 * pdf2word
 * @author yanglizdf
 */
public class PdfToWordTool {


    /** 涉及到的路径*/
    /** 1、pdf所在的路径，真实测试种是从外部引入的*/
    /**2、如果是大文件，需要进行切分，保存的子pdf路径*/
     String  splitPath = "./split/";
    /**3、如果是大文件，需要对子pdf文件一个一个进行转化*/
     String docPath = "./doc/";
     String distPath = "./dist/";


    private static final String WARN_STR_1 =" Evaluation Warning : The document was created with Spire.PDF for Java.";
    private static final String WARN_STR_2="Evaluation Warning : The document was created with Spire.PDF for java.";


    public String doConvertWord(String fileName, InputStream inputStream ) {
        // 1、最终生成的doc所在的目录，默认是和引入的一个地方，开源时对外提供下载的接口。
        String desPath = fileName.substring(0, fileName.length() - 4) + ".docx";
        desPath=distPath+desPath;
        boolean result = false;
        try {
            // 0、判断输入的是否是pdf文件
            //第一步：判断输入的是否合法
            //第二步：在输入的路径下新建文件夹
            boolean flag = createDir();
            if (!flag) {
                System.out.println("[数据平台][输入的不是pdf文件]");
                return "输入的不是pdf文件";
            }
            // 1、加载pdf
            PdfDocument pdf = new PdfDocument();

            pdf.loadFromStream(inputStream);
            //用 UsedFonts 属性获取文档中使用的所有字体
//            PdfUsedFont[] usedFonts = pdf.getUsedFonts();
//            for(PdfUsedFont font :usedFonts){
//                PdfFont newFont = new PdfFont(PdfFontFamily.Times_Roman, font.getSize(), PdfFontStyle.Italic);
//                font.replace(newFont);
//            }
            // 第一步：将其进行切分,每页一张pdf
            pdf.split(splitPath + "test{0}.pdf", 0);
            // 第二步：将切分的pdf，一个一个进行转换
            File[] fs = getSplitFiles(splitPath);
            CountDownLatch countDownLatch = new CountDownLatch(fs.length);
            WordPoolManager.newInstance().prepare();
            for (File file : fs) {
                Pdf2WordTask task= new Pdf2WordTask();
                task.setDocPath(docPath);
                task.setFile(file);
                task.setCountDownLatch(countDownLatch);
                WordPoolManager.newInstance().addExecuteTask(task);
            }
            countDownLatch.await();
            //第三步：对转化的doc文档进行合并，合并成一个大的word
            try {
                result =  merge2(docPath, desPath);
                System.out.println("[数据平台][result:"+ JSON.toJSONString(result)+"]]");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            /**4、把刚刚缓存的split和doc删除*/
            if (result) {
                FileUtils.clearFiles(splitPath);
                FileUtils.clearFiles(docPath);
            }
        }
        return desPath;
    }

    public  boolean merge(String docPath, String desPath) {
        //获取拆分的word文档
        File[] fs = getSplitFiles(docPath);
        Document document = new Document(docPath + "test0.docx");
        for (int i = 1; i < 15; i++) {
            document.insertTextFromFile(docPath + "test" + i + ".docx", FileFormat.Docx);
        }
        //消除警告提示语
        document.replace(Pattern.compile(WARN_STR_1),"");
        document.replace(Pattern.compile(WARN_STR_2),"");
        //第四步：对合并的doc进行保存2
        document.saveToFile(desPath, FileFormat.Docx);
        deleteWarn(desPath);
        return true;
    }

    public  boolean merge2(String docPath, String desPath) {
        //获取拆分的word文档
        File[] fs = getSplitFiles(docPath);
        Document document = new Document();
        for (int i = 0; i < fs.length; i++) {
            Document docToAppend = new Document();
            docToAppend.loadFromFile(docPath + "test" + i + ".docx", FileFormat.Docx_2013);
//            docToAppend.se
            document.importContent(docToAppend,true);
        }
        //消除警告提示语
        document.replace(Pattern.compile(WARN_STR_1),"");
        document.replace(Pattern.compile(WARN_STR_2),"");
        replaceFont(document);
        //第四步：对合并的doc进行保存2
        document.saveToFile(desPath, FileFormat.Docx_2013);
        document.close();
        deleteWarn(desPath);
        return true;
    }


    public void replaceFont(Document document) {
        document.setEmbedFontsInFile(true);
        // 遍历文档中的所有部分
        SectionCollection sections = document.getSections();
        for (int i=0;i< sections.getCount();i++) {
            Section section=sections.get(i) ;
            // 遍历每个部分中的段落和运行
            ParagraphCollection paragraphs = section.getParagraphs();
            for (int j=0;j<paragraphs.getCount();j++) {
                Paragraph  paragraph=paragraphs.get(j);
                CharacterFormat characterFormat = paragraph.getBreakCharacterFormat();
                System.out.println("fontName=====>"+characterFormat.getFontName());
                System.out.println("text=====>"+paragraph.getText());
                if ("Microsoft YaHei Bold".equals(characterFormat.getFontName()) && StrUtil.isNotBlank(paragraph.getText())) {
                    paragraph.getBreakCharacterFormat().setFontName("Microsoft YaHei");
                    paragraph.getBreakCharacterFormat().setBold(Boolean.TRUE);
                    paragraph.setText(paragraph.getText());
                    System.out.println("new text=====>"+paragraph.getText());
                } else if (characterFormat.getFontName().contains("Bold")) {
                    paragraph.getBreakCharacterFormat().setBold(Boolean.TRUE);
                    paragraph.setText(paragraph.getText());
                }

            }
        }

    }



    private   void deleteWarn(String desPath) {
        XWPFDocument document=null;
        try {
            InputStream is = new FileInputStream(desPath);
            document = new XWPFDocument(is);
            //以上Spire.Doc 生成的文件会自带警告信息，这里来删除Spire.Doc 的警告
            document.removeBodyElement(0);
//            replaceTextCustomization(document);
            //输出word内容文件流，新输出路径位置
            OutputStream os=new FileOutputStream(desPath);
            document.write(os);
            System.out.println("生成docx文档成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(document!=null){
                try {
                    document.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }



    private  boolean createDir() {
        File splitFile = new File(splitPath);
        File docFile = new File(docPath);
        File distFile =new File(distPath);
        if(!splitFile.exists()){splitFile.mkdirs();}
        if(!docFile.exists()){docFile.mkdirs();}
        if(!distFile.exists()){distFile.mkdirs();}
        return true;
    }

    /**取得某一路径下所有的pdf*/
    private  File[] getSplitFiles(String path) {
        File f = new File(path);
        File[] fs = f.listFiles();
        if (fs == null) {
            return null;
        }
        return fs;
    }

}
